﻿namespace UnityEditor
{
    using System;
    using System.Collections;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using UnityEditorInternal;
    using UnityEngine;

    internal class AvatarPreview
    {
        public int fps = 60;
        private const float kFloorAlpha = 0.5f;
        private const float kFloorFadeDuration = 0.2f;
        private const float kFloorScale = 5f;
        private const float kFloorScaleSmall = 0.2f;
        private const float kFloorShadowAlpha = 0.3f;
        private const float kFloorTextureScale = 4f;
        private const string kIkPref = "AvatarpreviewShowIK";
        private const int kPreviewLayer = 0x1f;
        private const string kReferencePref = "AvatarpreviewShowReference";
        private const string kSpeedPref = "AvatarpreviewSpeed";
        private const float kTimeControlRectHeight = 21f;
        private ModelImporterAnimationType m_AnimationClipType;
        private float m_BoundingVolumeScale;
        private GameObject m_DirectionInstance;
        private static Material m_FloorMaterial;
        private static Material m_FloorMaterialSmall;
        private Mesh m_FloorPlane;
        private Texture2D m_FloorTexture;
        private static bool m_IKOnFeet = false;
        private bool m_IsValid;
        private float m_NextFloorHeight;
        private OnAvatarChange m_OnAvatarChangeFunc;
        private GameObject m_PivotInstance;
        private float m_PrevFloorHeight;
        private Vector2 m_PreviewDir = new Vector2(120f, -20f);
        private int m_PreviewHint = "Preview".GetHashCode();
        private GameObject m_PreviewInstance;
        private PreviewRenderUtility m_PreviewUtility;
        private GameObject m_ReferenceInstance;
        private GameObject m_RootInstance;
        private static Material m_ShadowMaskMaterial;
        private static Material m_ShadowPlaneMaterial;
        private bool m_ShowIKOnFeetButton = true;
        private static bool m_ShowReference = false;
        private static string[] ms_DefaultAvatarPreview = new string[5];
        private const string s_PreviewStr = "Preview";
        private static Styles s_Styles;
        public TimeControl timeControl;

        public AvatarPreview(UnityEngine.Animator previewObjectInScene, Motion objectOnSameAsset)
        {
            this.InitInstance(previewObjectInScene, objectOnSameAsset);
        }

        public void AvatarTimeControlGUI(Rect rect)
        {
            Rect rect2 = rect;
            rect2.height = 21f;
            this.timeControl.DoTimeControl(rect2);
            rect.y = rect.yMax - 20f;
            float num = this.timeControl.currentTime - this.timeControl.startTime;
            EditorGUI.DropShadowLabel(new Rect(rect.x, rect.y, rect.width, 20f), string.Format("{0,2}:{1:00} ({2:000.0%})", (int) num, this.Repeat(Mathf.FloorToInt(num * this.fps), this.fps), this.timeControl.normalizedTime));
        }

        private static GameObject CalculatePreviewGameObject(UnityEngine.Animator selectedAnimator, Motion motion, ModelImporterAnimationType animationType)
        {
            AnimationClip firstAnimationClipFromMotion = GetFirstAnimationClipFromMotion(motion);
            string str = ms_DefaultAvatarPreview[(int) animationType];
            if (!string.IsNullOrEmpty(str))
            {
                GameObject go = AssetDatabase.LoadMainAssetAtPath(str) as GameObject;
                if (((go != null) && (GetAnimationType(go) == animationType)) && GameObjectInspector.HasRenderablePartsRecurse(go))
                {
                    return go;
                }
            }
            GameObject obj3 = FindBestFittingRenderableGameObjectFromModelAsset(firstAnimationClipFromMotion, animationType);
            if (obj3 != null)
            {
                return obj3;
            }
            if (animationType == ModelImporterAnimationType.Human)
            {
                return (GameObject) EditorGUIUtility.Load("Avatar/DefaultAvatar.fbx");
            }
            if (animationType == ModelImporterAnimationType.Generic)
            {
                return GetGenericAnimationFallback();
            }
            return null;
        }

        public void DoAvatarPreview(Rect rect, GUIStyle background)
        {
            this.Init();
            Rect position = rect;
            position.yMin += 21f;
            position.height = Mathf.Max(position.height, 64f);
            this.m_PreviewDir = PreviewGUI.Drag2D(this.m_PreviewDir, position);
            int controlID = GUIUtility.GetControlID(this.m_PreviewHint, FocusType.Native, position);
            EventType typeForControl = Event.current.GetTypeForControl(controlID);
            if ((typeForControl == EventType.Repaint) && this.m_IsValid)
            {
                Texture image = this.DoRenderPreview(position, background);
                GUI.DrawTexture(position, image, ScaleMode.StretchToFill, false);
            }
            this.AvatarTimeControlGUI(rect);
            if (!this.m_IsValid)
            {
                Rect rect3 = position;
                rect3.y += rect3.height / 2f;
                EditorGUI.LabelField(rect3, "No model is available for preview.\nPlease drag a model into the Preview Window.");
            }
            this.DoAvatarPreviewDrag(typeForControl);
        }

        public void DoAvatarPreviewDrag(EventType type)
        {
            if (type == EventType.DragUpdated)
            {
                DragAndDrop.visualMode = DragAndDropVisualMode.Link;
            }
            else if (type == EventType.DragPerform)
            {
                DragAndDrop.visualMode = DragAndDropVisualMode.Link;
                GameObject go = DragAndDrop.objectReferences[0] as GameObject;
                if ((go != null) && (GetAnimationType(go) == this.m_AnimationClipType))
                {
                    DragAndDrop.AcceptDrag();
                    ms_DefaultAvatarPreview[(int) this.m_AnimationClipType] = AssetDatabase.GetAssetPath(go);
                    UnityEngine.Object.DestroyImmediate(this.m_PreviewInstance);
                    this.InitInstance(go.GetComponent<UnityEngine.Animator>(), null);
                    if (this.m_OnAvatarChangeFunc != null)
                    {
                        this.m_OnAvatarChangeFunc();
                    }
                }
            }
        }

        public void DoPreviewSettings()
        {
            this.Init();
            if (this.m_ShowIKOnFeetButton)
            {
                EditorGUI.BeginChangeCheck();
                m_IKOnFeet = GUILayout.Toggle(m_IKOnFeet, s_Styles.ik, s_Styles.preButton, new GUILayoutOption[0]);
                if (EditorGUI.EndChangeCheck())
                {
                    EditorPrefs.SetBool("AvatarpreviewShowIK", m_IKOnFeet);
                }
            }
            EditorGUI.BeginChangeCheck();
            m_ShowReference = GUILayout.Toggle(m_ShowReference, s_Styles.pivot, s_Styles.preButton, new GUILayoutOption[0]);
            if (EditorGUI.EndChangeCheck())
            {
                EditorPrefs.SetBool("AvatarpreviewShowReference", m_ShowReference);
            }
            GUILayout.Box(s_Styles.speedScale, s_Styles.preLabel, new GUILayoutOption[0]);
            EditorGUI.BeginChangeCheck();
            this.timeControl.playbackSpeed = this.PreviewSlider(this.timeControl.playbackSpeed, 0.03f);
            if (EditorGUI.EndChangeCheck())
            {
                EditorPrefs.SetFloat("AvatarpreviewSpeed", this.timeControl.playbackSpeed);
            }
            GUILayout.Label(this.timeControl.playbackSpeed.ToString("f2"), s_Styles.preLabel, new GUILayoutOption[0]);
        }

        public Texture DoRenderPreview(Rect previewRect, GUIStyle background)
        {
            Quaternion bodyRotation;
            Vector3 bodyPosition;
            Quaternion rootRotation;
            Vector3 rootPosition;
            Vector3 pivotPosition;
            float humanScale;
            float prevFloorHeight;
            float num3;
            Matrix4x4 matrixx;
            this.m_PreviewUtility.BeginPreview(previewRect, background);
            if (this.Animator != null)
            {
                bodyRotation = this.Animator.bodyRotation;
                bodyPosition = this.Animator.bodyPosition;
                rootRotation = this.Animator.rootRotation;
                rootPosition = this.Animator.rootPosition;
                if (this.Animator.isHuman)
                {
                    pivotPosition = this.Animator.pivotPosition;
                    humanScale = this.Animator.humanScale;
                }
                else
                {
                    pivotPosition = Vector3.zero;
                    humanScale = this.m_BoundingVolumeScale / 2f;
                }
            }
            else
            {
                Vector3 vector4 = GameObjectInspector.GetRenderableCenterRecurse(this.m_PreviewInstance, 2, 8);
                bodyRotation = Quaternion.identity;
                bodyPosition = vector4;
                rootRotation = Quaternion.identity;
                rootPosition = Vector3.zero;
                pivotPosition = Vector3.zero;
                humanScale = this.m_BoundingVolumeScale / 2f;
            }
            bool oldFog = this.SetupPreviewLightingAndFx();
            Vector3 forward = (Vector3) (bodyRotation * Vector3.forward);
            forward[1] = 0f;
            Quaternion directionRot = Quaternion.LookRotation(forward);
            Vector3 directionPos = rootPosition;
            Quaternion pivotRot = rootRotation;
            this.PositionPreviewObjects(pivotRot, pivotPosition, bodyRotation, bodyPosition, directionRot, rootRotation, rootPosition, directionPos, humanScale);
            bool flag2 = Mathf.Abs((float) (this.m_NextFloorHeight - this.m_PrevFloorHeight)) > (humanScale * 0.01f);
            if (flag2)
            {
                float num4 = (this.m_NextFloorHeight >= this.m_PrevFloorHeight) ? 0.8f : 0.2f;
                prevFloorHeight = (this.timeControl.normalizedTime >= num4) ? this.m_NextFloorHeight : this.m_PrevFloorHeight;
                num3 = Mathf.Clamp01(Mathf.Abs((float) (this.timeControl.normalizedTime - num4)) / 0.2f);
            }
            else
            {
                prevFloorHeight = this.m_PrevFloorHeight;
                num3 = 1f;
            }
            Quaternion identity = Quaternion.identity;
            Vector3 floorPos = new Vector3(0f, 0f, 0f);
            floorPos = this.m_ReferenceInstance.transform.position;
            floorPos.y = prevFloorHeight;
            RenderTexture texture = this.RenderPreviewShadowmap(this.m_PreviewUtility.m_Light[0], humanScale, bodyPosition, floorPos, out matrixx);
            this.m_PreviewUtility.m_Camera.nearClipPlane = 1f * humanScale;
            this.m_PreviewUtility.m_Camera.farClipPlane = 25f * humanScale;
            Quaternion quaternion6 = Quaternion.Euler(-this.m_PreviewDir.y, -this.m_PreviewDir.x, 0f);
            Vector3 vector8 = ((Vector3) (quaternion6 * ((Vector3.forward * -5.5f) * humanScale))) + bodyPosition;
            this.m_PreviewUtility.m_Camera.transform.position = vector8;
            this.m_PreviewUtility.m_Camera.transform.rotation = quaternion6;
            floorPos.y = prevFloorHeight;
            Material floorMaterial = m_FloorMaterial;
            floorMaterial.mainTextureOffset = (Vector2) ((-floorMaterial.mainTextureScale * 0.5f) - (((new Vector2(floorPos.x, floorPos.z) / humanScale) * 0.1f) * 4f));
            floorMaterial.SetTexture("_ShadowTexture", texture);
            floorMaterial.SetMatrix("_ShadowTextureMatrix", matrixx);
            floorMaterial.SetVector("_Alphas", new Vector4(0.5f * num3, 0.3f * num3, 0f, 0f));
            Matrix4x4 matrix = Matrix4x4.TRS(floorPos, identity, (Vector3) ((Vector3.one * humanScale) * 5f));
            Graphics.DrawMesh(this.m_FloorPlane, matrix, floorMaterial, 0x1f, this.m_PreviewUtility.m_Camera, 0);
            if (flag2)
            {
                bool flag3 = this.m_NextFloorHeight > this.m_PrevFloorHeight;
                float to = !flag3 ? this.m_PrevFloorHeight : this.m_NextFloorHeight;
                float from = !flag3 ? this.m_NextFloorHeight : this.m_PrevFloorHeight;
                float num7 = ((to != prevFloorHeight) ? 1f : (1f - num3)) * Mathf.InverseLerp(from, to, rootPosition.y);
                floorPos.y = to;
                Material floorMaterialSmall = m_FloorMaterialSmall;
                floorMaterialSmall.mainTextureOffset = (Vector2) ((-floorMaterialSmall.mainTextureScale * 0.5f) - (((new Vector2(floorPos.x, floorPos.z) / humanScale) * 0.1f) * 4f));
                floorMaterialSmall.SetTexture("_ShadowTexture", texture);
                floorMaterialSmall.SetMatrix("_ShadowTextureMatrix", matrixx);
                floorMaterialSmall.SetVector("_Alphas", new Vector4(0.5f * num7, 0f, 0f, 0f));
                Matrix4x4 matrixx3 = Matrix4x4.TRS(floorPos, identity, (Vector3) ((Vector3.one * humanScale) * 0.2f));
                Graphics.DrawMesh(this.m_FloorPlane, matrixx3, floorMaterialSmall, 0x1f, this.m_PreviewUtility.m_Camera, 0);
            }
            this.SetPreviewCharacterEnabled(true, m_ShowReference);
            this.m_PreviewUtility.m_Camera.Render();
            this.SetPreviewCharacterEnabled(false, false);
            TeardownPreviewLightingAndFx(oldFog);
            RenderTexture.ReleaseTemporary(texture);
            return this.m_PreviewUtility.EndPreview();
        }

        public void DoSelectionChange()
        {
            this.m_OnAvatarChangeFunc();
        }

        public static GameObject FindBestFittingRenderableGameObjectFromModelAsset(UnityEngine.Object asset, ModelImporterAnimationType animationType)
        {
            if (asset != null)
            {
                ModelImporter atPath = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(asset)) as ModelImporter;
                if (atPath == null)
                {
                    return null;
                }
                GameObject go = AssetDatabase.LoadMainAssetAtPath(atPath.CalculateBestFittingPreviewGameObject()) as GameObject;
                if (((go != null) && GameObjectInspector.HasRenderablePartsRecurse(go)) && (GetAnimationType(go) == animationType))
                {
                    return go;
                }
            }
            return null;
        }

        public static ModelImporterAnimationType GetAnimationType(GameObject go)
        {
            UnityEngine.Animator component = go.GetComponent<UnityEngine.Animator>();
            Avatar avatar = (component == null) ? null : component.avatar;
            if (avatar != null)
            {
                if (avatar.isHuman)
                {
                    return ModelImporterAnimationType.Human;
                }
                return ModelImporterAnimationType.Generic;
            }
            if (go.GetComponent<Animation>() != null)
            {
                return ModelImporterAnimationType.Legacy;
            }
            return ModelImporterAnimationType.None;
        }

        public static ModelImporterAnimationType GetAnimationType(Motion motion)
        {
            AnimationClip firstAnimationClipFromMotion = GetFirstAnimationClipFromMotion(motion);
            if (firstAnimationClipFromMotion != null)
            {
                return AnimationUtility.GetAnimationType(firstAnimationClipFromMotion);
            }
            return ModelImporterAnimationType.None;
        }

        private static AnimationClip GetFirstAnimationClipFromMotion(Motion motion)
        {
            AnimationClip clip = motion as AnimationClip;
            if (clip != null)
            {
                return clip;
            }
            BlendTree tree = motion as BlendTree;
            if (tree != null)
            {
                AnimationClip[] animationClipsFlattened = tree.GetAnimationClipsFlattened();
                if (animationClipsFlattened.Length > 0)
                {
                    return animationClipsFlattened[0];
                }
            }
            return null;
        }

        private static GameObject GetGenericAnimationFallback()
        {
            return (GameObject) EditorGUIUtility.Load("Avatar/DefaultGeneric.fbx");
        }

        private void Init()
        {
            if (this.m_PreviewUtility == null)
            {
                this.m_PreviewUtility = new PreviewRenderUtility(true);
                this.m_PreviewUtility.m_CameraFieldOfView = 30f;
                this.m_PreviewUtility.m_Camera.cullingMask = -2147483648;
            }
            if (s_Styles == null)
            {
                s_Styles = new Styles();
            }
            if (this.m_FloorPlane == null)
            {
                this.m_FloorPlane = Resources.GetBuiltinResource(typeof(Mesh), "New-Plane.fbx") as Mesh;
            }
            if (this.m_FloorTexture == null)
            {
                this.m_FloorTexture = (Texture2D) EditorGUIUtility.Load("Avatar/Textures/AvatarFloor.png");
            }
            if (m_FloorMaterial == null)
            {
                Shader shader = EditorGUIUtility.LoadRequired("Previews/PreviewPlaneWithShadow.shader") as Shader;
                m_FloorMaterial = new Material(shader);
                m_FloorMaterial.mainTexture = this.m_FloorTexture;
                m_FloorMaterial.mainTextureScale = (Vector2) ((Vector2.one * 5f) * 4f);
                m_FloorMaterial.SetVector("_Alphas", new Vector4(0.5f, 0.3f, 0f, 0f));
                m_FloorMaterial.hideFlags = HideFlags.DontSave;
                m_FloorMaterialSmall = new Material(m_FloorMaterial);
                m_FloorMaterialSmall.mainTextureScale = (Vector2) ((Vector2.one * 0.2f) * 4f);
                m_FloorMaterialSmall.hideFlags = HideFlags.DontSave;
            }
            if (m_ShadowMaskMaterial == null)
            {
                Shader shader2 = EditorGUIUtility.LoadRequired("Previews/PreviewShadowMask.shader") as Shader;
                m_ShadowMaskMaterial = new Material(shader2);
                m_ShadowMaskMaterial.hideFlags = HideFlags.DontSave;
            }
            if (m_ShadowPlaneMaterial == null)
            {
                Shader shader3 = EditorGUIUtility.LoadRequired("Previews/PreviewShadowPlaneClip.shader") as Shader;
                m_ShadowPlaneMaterial = new Material(shader3);
                m_ShadowPlaneMaterial.hideFlags = HideFlags.DontSave;
            }
        }

        private void InitInstance(UnityEngine.Animator scenePreviewObject, Motion motion)
        {
            if (this.m_PreviewInstance == null)
            {
                if (motion != null)
                {
                    this.m_AnimationClipType = GetAnimationType(motion);
                }
                GameObject original = CalculatePreviewGameObject(scenePreviewObject, motion, this.m_AnimationClipType);
                this.m_IsValid = (original != null) && (original != GetGenericAnimationFallback());
                if (original != null)
                {
                    this.m_PreviewInstance = (GameObject) EditorUtility.InstantiateRemoveAllNonAnimationComponents(original, Vector3.zero, Quaternion.identity);
                    Bounds bounds = new Bounds(this.m_PreviewInstance.transform.position, Vector3.zero);
                    GameObjectInspector.GetRenderableBoundsRecurse(ref bounds, this.m_PreviewInstance);
                    this.m_BoundingVolumeScale = Mathf.Max(bounds.size.x, Mathf.Max(bounds.size.y, bounds.size.z));
                    InitInstantiatedPreviewRecursive(this.m_PreviewInstance);
                    if (this.Animator != null)
                    {
                        this.Animator.enabled = false;
                        this.Animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
                        this.Animator.applyRootMotion = true;
                    }
                }
            }
            if (this.timeControl == null)
            {
                this.timeControl = new TimeControl();
            }
            if (this.m_ReferenceInstance == null)
            {
                GameObject obj3 = (GameObject) EditorGUIUtility.Load("Avatar/dial_flat.prefab");
                this.m_ReferenceInstance = (GameObject) UnityEngine.Object.Instantiate(obj3, Vector3.zero, Quaternion.identity);
                InitInstantiatedPreviewRecursive(this.m_ReferenceInstance);
            }
            if (this.m_DirectionInstance == null)
            {
                GameObject obj4 = (GameObject) EditorGUIUtility.Load("Avatar/arrow.fbx");
                this.m_DirectionInstance = (GameObject) UnityEngine.Object.Instantiate(obj4, Vector3.zero, Quaternion.identity);
                InitInstantiatedPreviewRecursive(this.m_DirectionInstance);
            }
            if (this.m_PivotInstance == null)
            {
                GameObject obj5 = (GameObject) EditorGUIUtility.Load("Avatar/root.fbx");
                this.m_PivotInstance = (GameObject) UnityEngine.Object.Instantiate(obj5, Vector3.zero, Quaternion.identity);
                InitInstantiatedPreviewRecursive(this.m_PivotInstance);
            }
            if (this.m_RootInstance == null)
            {
                GameObject obj6 = (GameObject) EditorGUIUtility.Load("Avatar/root.fbx");
                this.m_RootInstance = (GameObject) UnityEngine.Object.Instantiate(obj6, Vector3.zero, Quaternion.identity);
                InitInstantiatedPreviewRecursive(this.m_RootInstance);
            }
            m_IKOnFeet = EditorPrefs.GetBool("AvatarpreviewShowIK", false);
            m_ShowReference = EditorPrefs.GetBool("AvatarpreviewShowReference", true);
            this.timeControl.playbackSpeed = EditorPrefs.GetFloat("AvatarpreviewSpeed", 1f);
            this.SetPreviewCharacterEnabled(false, false);
        }

        private static void InitInstantiatedPreviewRecursive(GameObject go)
        {
            go.hideFlags = HideFlags.HideAndDontSave;
            go.layer = 0x1f;
            IEnumerator enumerator = go.transform.GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    Transform current = (Transform) enumerator.Current;
                    InitInstantiatedPreviewRecursive(current.gameObject);
                }
            }
            finally
            {
                IDisposable disposable = enumerator as IDisposable;
                if (disposable == null)
                {
                }
                disposable.Dispose();
            }
        }

        public void OnDestroy()
        {
            if (this.m_PreviewUtility != null)
            {
                this.m_PreviewUtility.Cleanup();
                this.m_PreviewUtility = null;
            }
            UnityEngine.Object.DestroyImmediate(this.m_PreviewInstance);
            UnityEngine.Object.DestroyImmediate(m_FloorMaterial);
            UnityEngine.Object.DestroyImmediate(m_FloorMaterialSmall);
            UnityEngine.Object.DestroyImmediate(m_ShadowMaskMaterial);
            UnityEngine.Object.DestroyImmediate(m_ShadowPlaneMaterial);
            UnityEngine.Object.DestroyImmediate(this.m_ReferenceInstance);
            UnityEngine.Object.DestroyImmediate(this.m_RootInstance);
            UnityEngine.Object.DestroyImmediate(this.m_PivotInstance);
            UnityEngine.Object.DestroyImmediate(this.m_DirectionInstance);
            if (this.timeControl != null)
            {
                this.timeControl.OnDisable();
            }
        }

        private void PositionPreviewObjects(Quaternion pivotRot, Vector3 pivotPos, Quaternion bodyRot, Vector3 bodyPos, Quaternion directionRot, Quaternion rootRot, Vector3 rootPos, Vector3 directionPos, float scale)
        {
            this.m_ReferenceInstance.transform.position = rootPos;
            this.m_ReferenceInstance.transform.rotation = rootRot;
            this.m_ReferenceInstance.transform.localScale = (Vector3) ((Vector3.one * scale) * 1.25f);
            this.m_DirectionInstance.transform.position = directionPos;
            this.m_DirectionInstance.transform.rotation = directionRot;
            this.m_DirectionInstance.transform.localScale = (Vector3) ((Vector3.one * scale) * 2f);
            this.m_PivotInstance.transform.position = pivotPos;
            this.m_PivotInstance.transform.rotation = pivotRot;
            this.m_PivotInstance.transform.localScale = (Vector3) ((Vector3.one * scale) * 0.1f);
            this.m_RootInstance.transform.position = bodyPos;
            this.m_RootInstance.transform.rotation = bodyRot;
            this.m_RootInstance.transform.localScale = (Vector3) ((Vector3.one * scale) * 0.25f);
            if (this.Animator != null)
            {
                this.Animator.SetTarget(AvatarTarget.Root, 1f);
                float y = this.Animator.targetPosition.y;
                if (Mathf.Abs((float) (y - this.m_NextFloorHeight)) > (scale * 0.01f))
                {
                    this.m_PrevFloorHeight = this.m_NextFloorHeight;
                    this.m_NextFloorHeight = y;
                }
            }
        }

        private float PreviewSlider(float val, float snapThreshold)
        {
            GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.MaxWidth(64f) };
            val = GUILayout.HorizontalSlider(val, 0.1f, 2f, s_Styles.preSlider, s_Styles.preSliderThumb, options);
            if ((val > (0.25f - snapThreshold)) && (val < (0.25f + snapThreshold)))
            {
                val = 0.25f;
                return val;
            }
            if ((val > (0.5f - snapThreshold)) && (val < (0.5f + snapThreshold)))
            {
                val = 0.5f;
                return val;
            }
            if ((val > (0.75f - snapThreshold)) && (val < (0.75f + snapThreshold)))
            {
                val = 0.75f;
                return val;
            }
            if ((val > (1f - snapThreshold)) && (val < (1f + snapThreshold)))
            {
                val = 1f;
                return val;
            }
            if ((val > (1.25f - snapThreshold)) && (val < (1.25f + snapThreshold)))
            {
                val = 1.25f;
                return val;
            }
            if ((val > (1.5f - snapThreshold)) && (val < (1.5f + snapThreshold)))
            {
                val = 1.5f;
                return val;
            }
            if ((val > (1.75f - snapThreshold)) && (val < (1.75f + snapThreshold)))
            {
                val = 1.75f;
            }
            return val;
        }

        private RenderTexture RenderPreviewShadowmap(Light light, float scale, Vector3 center, Vector3 floorPos, out Matrix4x4 outShadowMatrix)
        {
            Camera camera = this.m_PreviewUtility.m_Camera;
            camera.orthographic = true;
            camera.orthographicSize = scale * 2f;
            camera.nearClipPlane = 1f * scale;
            camera.farClipPlane = 25f * scale;
            camera.transform.rotation = light.transform.rotation;
            camera.transform.position = center - ((Vector3) (light.transform.forward * (scale * 5.5f)));
            CameraClearFlags clearFlags = camera.clearFlags;
            camera.clearFlags = CameraClearFlags.Color;
            Color backgroundColor = camera.backgroundColor;
            camera.backgroundColor = new Color(0f, 0f, 0f, 0f);
            RenderTexture targetTexture = camera.targetTexture;
            RenderTexture texture2 = RenderTexture.GetTemporary(0x100, 0x100, 0x10);
            texture2.isPowerOfTwo = true;
            texture2.wrapMode = TextureWrapMode.Clamp;
            texture2.filterMode = UnityEngine.FilterMode.Bilinear;
            camera.targetTexture = texture2;
            this.SetPreviewCharacterEnabled(true, false);
            this.m_PreviewUtility.m_Camera.Render();
            RenderTexture.active = texture2;
            GL.PushMatrix();
            GL.LoadOrtho();
            m_ShadowMaskMaterial.SetPass(0);
            GL.Begin(7);
            GL.Vertex3(0f, 0f, -99f);
            GL.Vertex3(1f, 0f, -99f);
            GL.Vertex3(1f, 1f, -99f);
            GL.Vertex3(0f, 1f, -99f);
            GL.End();
            GL.LoadProjectionMatrix(camera.projectionMatrix);
            GL.LoadIdentity();
            GL.MultMatrix(camera.worldToCameraMatrix);
            m_ShadowPlaneMaterial.SetPass(0);
            GL.Begin(7);
            float x = 5f * scale;
            GL.Vertex(floorPos + new Vector3(-x, 0f, -x));
            GL.Vertex(floorPos + new Vector3(x, 0f, -x));
            GL.Vertex(floorPos + new Vector3(x, 0f, x));
            GL.Vertex(floorPos + new Vector3(-x, 0f, x));
            GL.End();
            GL.PopMatrix();
            Matrix4x4 matrixx = Matrix4x4.TRS(new Vector3(0.5f, 0.5f, 0.5f), Quaternion.identity, new Vector3(0.5f, 0.5f, 0.5f));
            outShadowMatrix = (matrixx * camera.projectionMatrix) * camera.worldToCameraMatrix;
            camera.orthographic = false;
            camera.clearFlags = clearFlags;
            camera.backgroundColor = backgroundColor;
            camera.targetTexture = targetTexture;
            return texture2;
        }

        private int Repeat(int t, int length)
        {
            return (((t % length) + length) % length);
        }

        private static void SetEnabledRecursive(GameObject go, bool enabled)
        {
            foreach (UnityEngine.Renderer renderer in go.GetComponentsInChildren<UnityEngine.Renderer>())
            {
                renderer.enabled = enabled;
            }
        }

        private void SetPreviewCharacterEnabled(bool enabled, bool showReference)
        {
            if (this.m_PreviewInstance != null)
            {
                SetEnabledRecursive(this.m_PreviewInstance, enabled);
            }
            SetEnabledRecursive(this.m_ReferenceInstance, showReference && enabled);
            SetEnabledRecursive(this.m_DirectionInstance, showReference && enabled);
            SetEnabledRecursive(this.m_PivotInstance, showReference && enabled);
            SetEnabledRecursive(this.m_RootInstance, showReference && enabled);
        }

        private bool SetupPreviewLightingAndFx()
        {
            this.m_PreviewUtility.m_Light[0].intensity = 0.7f;
            this.m_PreviewUtility.m_Light[0].transform.rotation = Quaternion.Euler(40f, 40f, 0f);
            this.m_PreviewUtility.m_Light[1].intensity = 0.7f;
            Color ambient = new Color(0.1f, 0.1f, 0.1f, 0f);
            InternalEditorUtility.SetCustomLighting(this.m_PreviewUtility.m_Light, ambient);
            bool fog = RenderSettings.fog;
            Unsupported.SetRenderSettingsUseFogNoDirty(false);
            return fog;
        }

        private static void TeardownPreviewLightingAndFx(bool oldFog)
        {
            Unsupported.SetRenderSettingsUseFogNoDirty(oldFog);
            InternalEditorUtility.RemoveCustomLighting();
        }

        public UnityEngine.Animator Animator
        {
            get
            {
                return ((this.m_PreviewInstance == null) ? null : (this.m_PreviewInstance.GetComponent(typeof(UnityEngine.Animator)) as UnityEngine.Animator));
            }
        }

        public bool IKOnFeet
        {
            get
            {
                return m_IKOnFeet;
            }
        }

        public OnAvatarChange OnAvatarChangeFunc
        {
            set
            {
                this.m_OnAvatarChangeFunc = value;
            }
        }

        public GameObject PreviewObject
        {
            get
            {
                return this.m_PreviewInstance;
            }
        }

        public bool ShowIKOnFeetButton
        {
            get
            {
                return this.m_ShowIKOnFeetButton;
            }
            set
            {
                this.m_ShowIKOnFeetButton = value;
            }
        }

        public delegate void OnAvatarChange();

        private class Styles
        {
            public GUIContent ik = new GUIContent("IK", "Activates feet IK preview");
            public GUIContent pivot = EditorGUIUtility.IconContent("AvatarPivot", "Displays avatar's pivot and mass center");
            public GUIStyle preButton = "preButton";
            public GUIStyle preLabel = "preLabel";
            public GUIStyle preSlider = "preSlider";
            public GUIStyle preSliderThumb = "preSliderThumb";
            public GUIContent speedScale = EditorGUIUtility.IconContent("SpeedScale", "Changes animation preview speed");
        }
    }
}

